﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using CSequence;
using Ini;
using Microsoft.VisualBasic.PowerPacks;
using System.Data.OleDb;
using System.Xml;
using System.Xml.XPath;



namespace Sequence
{
    public partial class FrmSequence2 : Form
    {
        string m_sPath;
        string m_sId;
        FileSequence oFileSequence = null;
        public OleDbConnection m_connection;

        class LineConnection 
        {
            public CStep oFrom;
            public CStep oTo;
            public LineShape dynamicLine;
            public int iControlIndex;
            public string sFromConnect;
            public string sToConnect;
        }

        private List<LineConnection> arrLineConnections = new List<LineConnection>();

        public string sId
        {
            get
            {
                return m_sId;
            }
            set
            {
                m_sId = value;
                tstbId.Text = m_sId;
                m_connection = GetConnection();
                oFileSequence = new FileSequence();

                String sSql = "select t_api_qd_process.name as process, t_api_qd_process_step.ID,t_api_qd_process_step.PROCESS_ID,";
                sSql += "          t_api_qd_process_step.NAME,t_api_qd_process_step.QUERY_NAME,t_api_qd_process_step.STEP_MODE, ";
                sSql += "          t_api_qd_process_step.TYPE sType ";
                sSql += "from t_api_qd_process ";
                sSql += "left outer join t_api_qd_process_step on  t_api_qd_process.id =  t_api_qd_process_step.process_id ";
                sSql += "where t_api_qd_process.id = " + m_sId + " ";
                sSql += "order by t_api_qd_process_step.ID";

                try
                {
                    OleDbCommand command = new OleDbCommand(sSql, m_connection);
                    OleDbDataReader oDataReader = command.ExecuteReader();
                    
                    while (oDataReader.Read())
                    {
                        tstbName.Text = oDataReader["PROCESS"].ToString();
                        if (oDataReader["ID"].ToString().Length > 0)
                        {
                            CStep oStep = new CStep(oDataReader, m_connection, oFileSequence);
                            AddParams(oStep);
                            oFileSequence.oSteps.Add(oStep);                            
                        }
                    }
                    oDataReader.Close();
                    oDataReader.Dispose();
                    command.Dispose();
                    oFileSequence.sName = tstbName.Text;
                    oFileSequence.bIsDirty = false;

                }
                catch (Exception ex)
                {
                    //WriteError(ex.Message + " (" + sSql + ")");
                }
                
                
                AddControls();
                AddLines();
                UpdateLines();
            }
        }

        private void AddParams(CStep oStep)
        {
            String sSql = "select * from T_API_QD_PROCESS_STEP_PARAMS where process_id=" + oStep.sProcessId + " and STEP_ID=" + oStep.sId;
            try
            {
                OleDbCommand command = new OleDbCommand(sSql, m_connection);
                OleDbDataReader oDataReader = command.ExecuteReader();

                while (oDataReader.Read())
                {
                    string sInName = oDataReader["NAME"].ToString();
                    string sInValue = oDataReader["PARAM_VALUE"].ToString();
                    string sID = oDataReader["ID"].ToString();
                    switch (oDataReader["PARAMS_TYPE"].ToString())
                    {
                        case "I":
                            if (sInName != null)
                            {
                                CInput oIn = new CInput(sInName, sInValue,sID, oStep);
                                oStep.lInputs.Add(oIn);
                            }

                            break;
                        case "O":
                            if (sInName != null)
                            {
                                COutput oOut = new COutput(sInName, sInValue,sID, oStep);
                                oStep.lOutputs.Add(oOut);
                            }
                            break;
                        case "D":
                            if (sInName != null)
                            {
                                CDisplay oDis = new CDisplay(sInName, sInValue,sID, oStep);
                                oStep.lDisplay.Add(oDis);
                            }
                            break;

                    }
                   
                }
                oDataReader.Close();
                oDataReader.Dispose();
                command.Dispose();

            }
            catch (Exception ex)
            {
                //WriteError(ex.Message + " (" + sSql + ")");
            }
        }

        public string Path
        {
            get
            {
                return m_sPath;
            }
            set
            {
                m_sPath = value;
                tstbPath.Text = m_sPath;
                if (m_sPath.Length > 0)
                {

                    oFileSequence = new FileSequence();
                    oFileSequence.sWorkingFolder = m_sPath;

                    try
                    {
                        string[] xmlFiles = Directory.GetFiles(m_sPath, "*.xml");

                        foreach (string sIn in xmlFiles)
                        {
                            CStep oStep = new CStep(sIn, oFileSequence);
                            oFileSequence.oSteps.Add(oStep);
                        }
                    }
                    catch (Exception e)
                    {
                        rtbErrors.Text += e.Message ;
                    } 
                   
                    AddControls();
                    AddLines();
                }
            }
        }

        private void AddLines()
        {
            List<string> lKeys = new List<string>();
            int i = 0;
            foreach (CStep oSt in oFileSequence.oSteps)
            {
                foreach (CInput oIn in oSt.lInputs)
                {
                    string[] sInputs = oIn.sValue.Split('>');
                    if (sInputs.Count() == 2)
                    {
                        CStep oStTo = oFileSequence.oSteps.Find(element => element.sName == sInputs[0]);
                        if (oStTo != null)
                        {
                            // Now we need to find the Output Param for the oStTo step
                            COutput oOut = oStTo.lOutputs.Find(element => element.sName == sInputs[1]);

                            if (oOut != null)
                            {
                                int iX1 = GetX1(oSt), iX2 = GetX2(oStTo);
                                int iY1 = GetY1(oSt, sInputs[1]), iY2 = GetY2(oStTo, sInputs[1]);


                                LineShape dynamicLine = new LineShape();
                                ShapeContainer sc = new ShapeContainer();
                                dynamicLine.Parent = sc;
                                dynamicLine.X1 = iX1; dynamicLine.X2 = iX2;
                                dynamicLine.Y1 = iY1; dynamicLine.Y2 = iY2;

                                LineConnection oLineConnections = new LineConnection();
                                oLineConnections.oFrom = oSt;
                                oLineConnections.oTo = oStTo;
                                oLineConnections.dynamicLine = dynamicLine;
                                oLineConnections.sFromConnect = oIn.sName;
                                oLineConnections.sToConnect = oOut.sName;
                                sc.Name = "LineConnection" + i.ToString();
                                arrLineConnections.Add(oLineConnections);

                                dynamicLine.Visible = true;
                                panel1.Controls.Add(sc);
                                oLineConnections.iControlIndex = i;
                                i++;
                            }
                               
                        }
                    }
                }
            }
        }

        private void AddControls()
        {            
            panel1.Controls.Clear();
            int i = 0;
            foreach (CStep oSt in oFileSequence.oSteps)
            {
                usStep dynamicStep = new usStep(oSt, contextMenuStrip1);
                dynamicStep.Name = "usStep" + i.ToString();
                panel1.Controls.Add(dynamicStep);
                oSt.iControlIndex = i;
                i++;
            }
        }

        private void UpdateLines()
        {
            foreach (LineConnection oLineConn in arrLineConnections)
            {
                int iX1 = GetX1(oLineConn.oFrom),iX2 = GetX2(oLineConn.oTo);
                int iY1 = GetY1(oLineConn.oFrom, oLineConn.sFromConnect), iY2 = GetY2(oLineConn.oTo, oLineConn.sToConnect);              

                oLineConn.dynamicLine.X1 = iX1; oLineConn.dynamicLine.X2 = iX2;
                oLineConn.dynamicLine.Y1 = iY1; oLineConn.dynamicLine.Y2 = iY2;
                //panel1.Controls["LineConnection" + oLineConn.iControlIndex.ToString()].BringToFront();
            }
        }

        private int GetY1(CStep oSt, string sName)
        {
            return Convert.ToInt16(oSt.GetDisplayValue("Y")) + ((usStep)(panel1.Controls["usStep" + oSt.iControlIndex.ToString()])).GetInputOffset(sName);
        }

        private int GetY2(CStep oSt, string sName)
        {
            return Convert.ToInt16(oSt.GetDisplayValue("Y")) + ((usStep)(panel1.Controls["usStep" + oSt.iControlIndex.ToString()])).GetOutputOffset(sName);
        }


        private int GetX1(CStep oSt)
        {
            return Convert.ToInt16(oSt.GetDisplayValue("X")); 
        }

        private int GetX2(CStep oSt)
        {            
            return Convert.ToInt16(oSt.GetDisplayValue("X")) + (Convert.ToInt16(oSt.GetDisplayValue("Width")));
        }

        public FrmSequence2()
        {
            InitializeComponent();
            
        }

        public OleDbConnection GetConnection()
        {
            return ((Sequence.MDISequence)(this.MdiParent)).GetConnection();
        }

        private void FrmSequence_Load(object sender, EventArgs e)
        {
            this.Text = "Sequence -" + m_sPath;
        }

        private float GetScale()
        {
            string sScale = cboScale.Text.Replace("%", "");
            sScale = sScale.Replace(" ", "");
            return (float)(Convert.ToDouble(sScale) / 100.0F);
        }

        private void upToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            { 
                oSt.SetDisplayValue("Y", (Convert.ToDouble(oSt.GetDisplayValue("Y","0")) - 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void downToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            {
                oSt.SetDisplayValue("Y", (Convert.ToDouble(oSt.GetDisplayValue("Y","0")) + 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void rightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            {
                string sX = oSt.GetDisplayValue("X");
                if (sX.Length == 0)
                    sX = "0";
                oSt.SetDisplayValue("X", (Convert.ToDouble(sX) + 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void leftToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            {
                oSt.SetDisplayValue("X", (Convert.ToDouble(oSt.GetDisplayValue("X","0")) - 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            //Console.WriteLine(e.ToString());
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            //Console.WriteLine(e.ToString());
        }

        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            //Console.WriteLine(e.ToString());
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void incHeightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            {
                oSt.SetDisplayValue("Height", (Convert.ToDouble(oSt.GetDisplayValue("Height","100")) + 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void decHeightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            {
                oSt.SetDisplayValue("Height", (Convert.ToDouble(oSt.GetDisplayValue("Height","100")) - 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void incWidthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            {
                oSt.SetDisplayValue("Width", (Convert.ToDouble(oSt.GetDisplayValue("Width","100")) + 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void decWidthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oSt = FindFocusStep();
            if (oSt != null)
            {
                oSt.SetDisplayValue("Width", (Convert.ToDouble(oSt.GetDisplayValue("Width","100")) - 5).ToString());
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).SetLocation();
                UpdateLines();
                ((usStep)panel1.Controls["usStep" + oSt.iControlIndex.ToString()]).Refresh();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void cboSteps_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }

        private void cmdRun_Click(object sender, EventArgs e)
        {
           
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {

        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            ShowProperties();        
        }

        private void ShowProperties()
        {
            CheckToSave();
            FrmProperties oFrmProperties = new FrmProperties();
            oFrmProperties.m_connection = GetConnection();

            CStep oStep = FindFocusStep();
            if (oStep != null)
            {
                oFrmProperties.LoadData(oStep);
                oFrmProperties.ShowDialog(this);
                if (oFrmProperties.bToSave)
                {
                    oStep = oFrmProperties.m_oStep;
                    ((usStep)panel1.Controls["usStep" + oStep.iControlIndex]).Display(oStep, contextMenuStrip1);
                    oFileSequence.bIsDirty = true;
                    Text = oFileSequence.GetProcessName();
                }
            }
        }
        private void CheckToSave()
        {
            if (oFileSequence.bIsDirty)
            {
                if (MessageBox.Show("Save changes first", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    Save();
                }
            }
        }

        private CStep FindFocusStep()
        {
            CStep oStep = null;
            foreach (Control oCon in panel1.Controls)
            {
                if (oCon.GetType() == typeof(usStep))
                {
                    if (((usStep)oCon).bHasFocus)
                    {
                       oStep = oFileSequence.FindStep(oCon.Text);
                    }
                }
            }
            return oStep;
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            CheckToSave();
            Cursor.Current = Cursors.WaitCursor;
            ClearCalValue();
            rtbErrors.Text = "Started as " + DateTime.Now.ToString() + "\r\n";
            oFileSequence.bIfElseFlag = false;

            // Get all the inputs ( ? ) 
            List<string> arrInputs = new List<string>();
            foreach (CStep oSt in oFileSequence.oSteps)
            {
                foreach (CInput oIn in oSt.lInputs)
                {
                    if (oIn.sValue == "?")
                        arrInputs.Add(oSt.sName + "." + oIn.sName);
                }
            }
            
            // Get any user inputs 
            GetInputs(arrInputs);
            
            if (oFileSequence.oSteps.Count > 0)
            {
                DateTime dStart = DateTime.Now;
                StartStats(dStart.ToString());                
                
                // Now run each step on order
                oFileSequence.iCurrentStep = 0; 
                bool bFinished=false;
                while (!bFinished)                
                {
                    if (oFileSequence.iCurrentStep < oFileSequence.oSteps.Count())
                    {
                        CStep oSt = oFileSequence.oSteps[oFileSequence.iCurrentStep];
                        if (ToRunStep(oSt))
                        {
                            rtbErrors.Text += "    Running step " + oSt.sName + "\r\n";
                            rtbErrors.Refresh();
                            oSt.Calculate();
                        }
                        else
                        {
                            rtbErrors.Text += "    Step '" + oSt.sName + "' skipped due to if step \r\n";
                        }
                        oFileSequence.iCurrentStep++;
                        Application.DoEvents();
                    }    
                    else
                        bFinished = true;
                }



                rtbErrors.Text += "Finished at " + DateTime.Now.ToString();

                DateTime dEnd = DateTime.Now;
                EndStats(dEnd.ToString());
                if (oFileSequence.sLastError != "")
                    rtbErrors.Text += oFileSequence.sLastError;

                string sRes = oFileSequence.oSteps[oFileSequence.oSteps.Count() -1].GetResults() + "\r\nTime " + dEnd.Subtract(dStart).TotalMilliseconds.ToString() + " ms";
                Cursor.Current = Cursors.Default;
                                              
                //Results oRes = new Results(sRes, sResFilename);
                //oRes.ShowDialog(this);
                MessageBox.Show(sRes, "Results", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private bool ToRunStep(CStep oStep )
        {
            bool bRet = true;

            if (oFileSequence.bIfElseFlag != false)
            {
                if ((oStep.sType != "IF") && (oStep.sType != "ELSE") && (oStep.sType != "END IF"))
                    bRet = false;
            }
            return bRet;
        }

        private void GetInputs(List<string> arrInputs)
        {
            if (arrInputs.Count() > 0)
            {
                FrmGetValues oFrmGetValues = new FrmGetValues(arrInputs);
                oFrmGetValues.ShowDialog();
                if (oFrmGetValues.arrResults != null)
                {

                    foreach (string sVal in oFrmGetValues.arrResults)
                    {
                        string[] arrRes = sVal.Split('\t');
                        if (arrRes.Count() == 2)
                        {
                            string[] arrStepName = arrRes[0].Split('.');
                            if (arrStepName.Count() == 2)
                            {
                                CStep oStep = oFileSequence.oSteps.Find(element => element.sName == arrStepName[0]);
                                if (oStep != null)
                                {
                                    CInput oInput = oStep.lInputs.Find(element => element.sName == arrStepName[1]);
                                    if (oInput != null)
                                        oInput.sCalValue = arrRes[1];
                                }
                            }
                        }
                    }
                }
            }
        }

        private void StartStats(string sTime)
        {
            IniFile oIni = new Ini.IniFile(Path + "\\Stats.ini");
            oFileSequence.m_RunNum = Convert.ToInt16(oIni.IniReadValue("Settings", "NextRunNumber", "0"));

            oIni.IniWriteValue("Settings", "NextRunNumber", (oFileSequence.m_RunNum + 1).ToString());

            string sRunNumList = oIni.IniReadValue("Settings", "RunNumList", "");
            if (sRunNumList == "")
                sRunNumList += oFileSequence.m_RunNum.ToString();
            else
                sRunNumList += "," + oFileSequence.m_RunNum.ToString();
            oIni.IniWriteValue("Settings", "RunNumList", sRunNumList);
            oIni.IniWriteValue("Run-" + oFileSequence.m_RunNum.ToString(), "Start", sTime);
        }

        private void EndStats(string sTime)
        {
            IniFile oIni = new Ini.IniFile(Path + "\\Stats.ini");
            oIni.IniWriteValue("Run-" + oFileSequence.m_RunNum.ToString(), "End", sTime);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void cboScale_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            ClearCalValue();
            Invalidate();
        }

        private void ClearCalValue()
        {
            foreach (CStep oStep in oFileSequence.oSteps)
            {
                oStep.bCalculated = false;
                foreach (COutput oOut in oStep.lOutputs)
                    oOut.sCalValue = "";
                foreach (CInput oIn in oStep.lInputs)
                    oIn.sCalValue = "";
            }
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            if (toolStripButton4.ToolTipText == "Show Name")
            {
                toolStripButton4.ToolTipText = "Show Values";
                toolStripButton4.Image = Properties.Resources.Properties;
                foreach (Control oCon in panel1.Controls)
                {
                    if (oCon.GetType() == typeof(usStep))
                        ((usStep)oCon).ShowType = usStep.eShowType.Values;
                }
            }
            else
            {
                toolStripButton4.ToolTipText = "Show Name";
                toolStripButton4.Image = Properties.Resources.Values;
                foreach (Control oCon in panel1.Controls)
                {
                    if (oCon.GetType() ==  typeof(usStep) )
                        ((usStep)oCon).ShowType = usStep.eShowType.Names;
                }
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            ProcessStartInfo pi = new ProcessStartInfo(tstbPath.Text);
            //pi.Arguments = Path.GetFileName(tbWorkingFolder.Text);
            pi.UseShellExecute = true;
            pi.WorkingDirectory = tstbPath.Text;
            pi.FileName = tstbPath.Text;
            pi.Verb = "OPEN";

            try
            {
                Process.Start(pi);
            }
            catch (Exception ex)
            {
                rtbErrors.Text += ex.Message + " (" + tstbPath.Text + ")\r\n";
            }
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            CheckToSave();
            RefreshScreen();
        }

        private void RefreshScreen()
        {
            
            Path = tstbPath.Text;
            sId = tstbId.Text;
            Text = oFileSequence.GetProcessName();
            panel1.Refresh();
        }

        private void RunSql(String sSql)
        {
            try
            {
                OleDbCommand command = new OleDbCommand(sSql, GetConnection());
                int iRows = command.ExecuteNonQuery();
                
                command.Dispose();
            }
            catch (Exception ex)
            {
                rtbErrors.Text += ex.Message + " (" + sSql + ")\r\n";
            }
        }

        private void tsbNew_Click(object sender, EventArgs e)
        {
            CheckToSave();
            string sSql = "insert into T_API_QD_PROCESS_STEP (PROCESS_ID,ID,NAME,TYPE,QUERY_NAME ) values (" + sId + ",(select Nvl(max(ID),0)+1 from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),'New',1,'New')";
            RunSql(sSql);

            sSql = "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),1,'D','X','385')";
            RunSql(sSql);
            sSql = "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),2,'D','Y','180')";
            RunSql(sSql);
            sSql = "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),3,'D','Height','110')";
            RunSql(sSql);
            sSql = "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),4,'D','Width','200')";
            RunSql(sSql);
            RefreshScreen();
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
            Save();
        }

        public void Save()
        {
            Cursor.Current = Cursors.WaitCursor;
            oFileSequence.bIsDirty = false;
            if (tstbId.Text == "")
                RunSql("insert into T_API_QD_PROCESS (ID,NAME) values((select Nvl(max(ID),0)+1 from T_API_QD_PROCESS), '" + tstbName.Text + "' )");
            else
                RunSql("Update T_API_QD_PROCESS set NAME='" + tstbName.Text + "' where ID=" + tstbId.Text);

            foreach (CStep oStep in oFileSequence.oSteps)
                oStep.Save();

            Text = oFileSequence.GetProcessName();
            Cursor.Current = Cursors.Default;
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem ts = (ToolStripMenuItem)sender;
            if (ts != null)
            {
                ContextMenuStrip cMenu = ts.Owner as ContextMenuStrip;

                if (cMenu != null)
                {
                    RichTextBox rtb = (RichTextBox)cMenu.SourceControl;
                    rtb.SelectAll();
                }
            }
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem ts = (ToolStripMenuItem)sender;
            if (ts != null)
            {
                ContextMenuStrip cMenu = ts.Owner as ContextMenuStrip;

                if (cMenu != null)
                {
                    RichTextBox rtb = (RichTextBox)cMenu.SourceControl;
                    if (rtb.SelectedText != "")
                        Clipboard.SetText(rtb.SelectedText);
                }
            }
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem ts = (ToolStripMenuItem)sender;
            if (ts != null)
            {
                ContextMenuStrip cMenu = ts.Owner as ContextMenuStrip;

                if (cMenu != null)
                {
                    RichTextBox rtb = (RichTextBox)cMenu.SourceControl;
                    rtb.Paste();
                }
            }
        }

        private void tsbImport_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog oFolderBrowserDialog = new FolderBrowserDialog();
            oFolderBrowserDialog.ShowDialog(this);
            if (oFolderBrowserDialog.SelectedPath.Length > 0)
            {
                string[] dirs = Directory.GetFiles(oFolderBrowserDialog.SelectedPath, "*-In.xml");
                int iX = 0, iY = 0;
                foreach (string sFilename in dirs)
                {

                    if (sFilename.IndexOf("-BLCommand") < 0)
                    {
                        AddStepFromFile(sFilename, iX, iY);
                        iX++;
                        if ((iX % 7) == 0)
                        {
                            iX = 0;
                            iY += 1;
                        }
                    }
                }
                RefreshScreen();
            }
        }

        void AddStepFromFile(string sFilename, int iX, int iY)
        {
            
            // Make sure the possition is valid 
            if ( iX < 0) iX=0; if ( iY < 0) iY=0;


            string sQD = "", sType = "1", sProcess = "", sMode="";
            List<string> arrInputs = new List<string>();

            XmlDocument oXmlDoc = new XmlDocument();
            try
            {
                string sXml = "";
                using (StreamReader sr = new StreamReader(sFilename))
                {
                    sXml = sr.ReadToEnd();
                    sXml = sXml.Replace("<?xml version=\"1.0\" encoding=\"UTF8\"?>", "");
                }
                oXmlDoc.LoadXml(sXml);
                XmlNode oNodeMethod = oXmlDoc.SelectSingleNode("/Root/XMLHeader/MethodName/text()");
                if (oNodeMethod == null)
                {
                    rtbErrors.Text += "Incorrect xml file format (no value at /Root/XMLHeader/MethodName)";
                }
                else
                {
                    XmlNode oNode = null;
                    if (oNodeMethod.Value == "QueryDef")
                    {
                        oNode = oXmlDoc.SelectSingleNode("/Root/XMLBody/Queries/Query/@Name");
                        sQD = oNode.Value;
                        string[] sArr = sQD.Split('.');
                        sProcess = sArr[sArr.Count() - 1];
                        sType = "1";
                       
                        
                        //Make Sure the name is unique
                        foreach (CStep oStep in oFileSequence.oSteps)
                        {
                            if (oStep.sName == sProcess)
                                sProcess += "1";
                        }

                        //Now get all the inputs 
                        XmlNodeList xnList = oXmlDoc.SelectSingleNode("/Root/XMLBody/Queries/Query/Param").ChildNodes;

                        foreach (XmlNode xn in xnList)
                        {
                            arrInputs.Add(xn.Name + "\t" + xn.InnerText);
                        }


                    }
                    else
                    {
                        oNode = oXmlDoc.SelectSingleNode("/Root/XMLBody/Updates/Update/@Name");
                        sQD = oNode.Value;
                        sMode = oXmlDoc.SelectSingleNode("/Root/XMLBody/Updates/Update/@Mode").Value;

                        string[] sArr = sQD.Split('.');
                        sProcess = sArr[sArr.Count() - 1];
                        sType = "2";
                        //Make Sure the name is unique
                        foreach (CStep oStep in oFileSequence.oSteps)
                        {
                            if (oStep.sName == sProcess)
                                sProcess += "1";
                        }

                        //Now get all the inputs 
                        XmlNodeList xnList = oXmlDoc.SelectSingleNode("/Root/XMLBody/Updates/Update").ChildNodes;
                        
                        foreach (XmlNode xn in xnList)
                        {
                            arrInputs.Add(xn.Name + "\t" + xn.InnerText);
                        }
                    }

                    if (oNode != null)
                    {
                        string sSql = "Begin\r\nInsert into T_API_QD_PROCESS_STEP (PROCESS_ID,ID,NAME,TYPE,QUERY_NAME,STEP_MODE ) values (" + sId + ",(select Nvl(max(ID),0)+1 from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),'" + sProcess + "'," + sType + ",'" + sQD + "','" + sMode + "');\r\n";
                        sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),1,'D','X','" + (15 + iX * 210).ToString() + "');\r\n";
                        sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),2,'D','Y','" + (15 + iY * 120).ToString() + "');\r\n";
                        sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),3,'D','Height','110');\r\n";
                        sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),4,'D','Width','200');\r\n\r\n";
                        int i = 5;
                        foreach (string sStepParam in arrInputs)
                        {
                            string[] arrStepParam = sStepParam.Split('\t');
                            sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAM_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + ")," + i.ToString() + ",'I','" + arrStepParam[0] + "','" + arrStepParam[1] + "');\r\n";
                            i++;
                        }
                        sSql += "end;\r\n";
                        RunSql(sSql);

                    }
                }
            }
            catch (Exception ex)
            {
                rtbErrors.Text += ex.Message + "\r\n";
            }
        }

        private void contextMenuStrip2_Opening(object sender, CancelEventArgs e)
        {

        }

        private void runStepToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();

            if (oStep == null)
            {
                rtbErrors.Text += "Select a step";
            }
            else
            {
                // Get all the inputs ( ? ) 
                List<string> arrInputs = new List<string>();
                rtbErrors.Text = "Started as " + DateTime.Now.ToString() + "\r\n";
                foreach (CInput oIn in oStep.lInputs)
                {
                    if (oIn.sValue == "?")                   
                        arrInputs.Add(oStep.sName + "." + oIn.sName);                   
                }

                // If there are any inputs that need to be input by the user
                GetInputs(arrInputs);


                // Update all the fixed values 
                foreach (CInput oIn in oStep.lInputs)
                {
                    if ((oIn.sValue != "?") && (oIn.sValue.IndexOf('>') < 0) && (oIn.sValue.IndexOf('=') != 1))                    
                        oIn.sCalValue = oIn.sValue;
                    
                }


                if (oStep != null)
                {
                    oStep.Calculate();
                    if (oStep.sType == "IF")
                        rtbErrors.Text += "    If returned " + (oFileSequence.bIfElseFlag == false).ToString() + "\r\n";
                }
                
                foreach (COutput oOut in oStep.lOutputs)
                    rtbErrors.Text += "    " + oOut.sName + " : " + oOut.sCalValue + "\r\n";


                rtbErrors.Text += "Finished as " + DateTime.Now.ToString() + "\r\n";
            }
        }


 
        private void showResultsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();
            if (oStep == null)
            {
                rtbErrors.Text += "Select a step";
            }
            else
            {
                Results oRes = new Results(oStep.sErrorMessage, oStep.sLastRunInXml, oStep.sLastRunOutXml);
                oRes.ShowDialog(this);
            }
        }

        private void panel1_DragEnter(object sender, DragEventArgs e)
        {
            //rtbErrors.Text += "panel1_DragEnter";
            if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
        }

        private void panel1_DragDrop(object sender, DragEventArgs e)
        {
            //rtbErrors.Text += "panel1_DragDrop";
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            Point oCurrent = Cursor.Position;
            foreach (string sFilename in files)
            {
                //Console.WriteLine(file);
                if (sFilename.Substring(sFilename.Length - 3, 3).ToLower() == "xml")
                {
                    int iX = ((oCurrent.X - 15) / 210), iY = (oCurrent.Y - 15) / 120;
                    AddStepFromFile(sFilename, iX, iY);
                    RefreshScreen();
                }
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();
            if (oStep == null)
            {
                rtbErrors.Text += "Select a step";
            }
            else
            {
                string sSql = "Begin\r\ndelete from  t_api_qd_process_step where process_id=" + sId + " and id = " + oStep.sId + ";\r\n ";
                sSql += "delete from  t_api_qd_process_step_params where process_id=" + sId + " and step_id = " + oStep.sId + ";\r\nend;\r\n";
                RunSql(sSql);
                RefreshScreen();
            }
        }

        private void reorderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmReorder oFrmReorder = new FrmReorder(ref oFileSequence);
            oFrmReorder.ShowDialog(this);
            if (oFrmReorder.bToSave)
            {
                string sSql = "Begin \r\n";
                sSql += "delete from T_API_QD_PROCESS_STEP where PROCESS_ID=" + tstbId.Text + ";\r\n";
                sSql += "delete from T_API_QD_PROCESS_STEP_PARAMS where PROCESS_ID=" + tstbId.Text + ";\r\n";                
                sSql += "end;";
                RunSql(sSql);                              
                Save();
                RefreshScreen();
            }
        }

        private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowProperties();
        }
    }
}
